﻿using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace XHXTools
{
    /// <summary>
    /// 读取Json文件信息
    /// </summary>
    public class ReadJson
    {

        #region 使用 Newtonsoft.Json 包

        /// <summary>
        /// 读取json文件中的json数据到实体类
        /// </summary>
        /// <typeparam name="T">泛型</typeparam>
        /// <param name="key">json文件中相对应的key</param>
        /// <param name="jsonFileName">json文件名称</param>
        /// <param name="jsonFilePath">指定json文件路径————不输入路径，默认为当前程序集集路径</param>
        /// <returns>返回 T </returns>
        public T ReadJsonToClass<T>(string key, string jsonFileName, string jsonFilePath = null)
        {

            try
            {
                jsonFilePath = string.IsNullOrEmpty(jsonFilePath) ? AppContext.BaseDirectory : jsonFilePath;
                //打开文件并读取
                using (StreamReader streamReader = File.OpenText(Path.Combine(jsonFilePath, jsonFileName)))
                {
                    // 使用json读取器读取json数据
                    using (JsonTextReader jsonTextReader = new JsonTextReader(streamReader))
                    {
                        JObject jobject = (JObject)JToken.ReadFrom(jsonTextReader);
                        T t = JsonConvert.DeserializeObject<T>(jobject[key].ToString());
                        return t;
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }


        /// <summary>
        /// 读取json文件中数据到字符串——默认程序集根目录
        /// </summary>
        /// <param name="key">json文件中相对应的key</param>
        /// <param name="jsonFileName">json文件名称</param>
        /// <param name="jsonFilePath">指定json文件路径————不输入路径，默认为当前程序集集路径</param>
        /// <returns>返回字符串</returns>
        public string ReadJsonToString(string key, string jsonFileName, string jsonFilePath = null)
        {
            try
            {
                jsonFilePath = string.IsNullOrEmpty(jsonFilePath) ? AppContext.BaseDirectory : jsonFilePath;
                //打开文件并读取
                using (StreamReader streamReader = File.OpenText(Path.Combine(AppContext.BaseDirectory, jsonFileName)))
                {
                    // 使用json读取器读取json数据
                    using (JsonTextReader jsonTextReader = new JsonTextReader(streamReader))
                    {
                        JObject jobject = (JObject)JToken.ReadFrom(jsonTextReader);
                        string t = jobject[key].ToString();
                        return t;
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        #endregion

        #region 使用官方 Configuration 包

        /// <summary>
        /// 使用配置加载json文件到对象
        /// </summary>
        /// <typeparam name="T">泛型</typeparam>
        /// <param name="key">json文件中需要读取的键</param>
        /// <param name="jsonFileName">json文件名</param>
        /// <param name="jsonFilePath">json文件路径</param>
        /// <returns>T</returns>
        public T UseConfigurationReadJson<T>(string key, string jsonFileName, string jsonFilePath = null)
        {
            try
            {
                ConfigurationBuilder builder = new ConfigurationBuilder();
                jsonFilePath = string.IsNullOrEmpty(jsonFilePath) ? AppContext.BaseDirectory : jsonFilePath;
                IConfiguration config = builder.SetBasePath(jsonFilePath).AddJsonFile(jsonFileName, true, true).Build();
                T t = config.GetSection(key).Get<T>();
                return t;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 使用配置加载json文件转换到对象，多层级结构
        /// 最后一个参数不需要传入
        /// </summary>
        /// <typeparam name="T">输入的类型</typeparam>
        /// <param name="keyList">json文件中需要读取的键————例如:需要取 A.b.C 的值或对象，集合为 {"A","b","C"}</param>
        /// <param name="jsonFileName">json文件名</param>
        /// <param name="jsonFilePath">json文件路径，不传路径默认为当前程序集路径</param>
        /// <returns>
        /// 返回为 null 没有找到当前值，请检查key值是否正确或输入 类型 T 是否正确
        /// 主要异常：InvalidOperationException——没有找到值或不能转换为当前输入的T
        /// </returns>
        public T UseConfigurationReadJson<T>(List<string> keyList, string jsonFileName, string jsonFilePath = null)
        {
            try
            {
                ConfigurationBuilder builder = new ConfigurationBuilder();
                jsonFilePath = string.IsNullOrEmpty(jsonFilePath) ? AppContext.BaseDirectory : jsonFilePath;
                builder.SetBasePath(jsonFilePath);//设置文件路径
                builder.AddJsonFile(jsonFileName, true, true);//添加文件名称
                IConfiguration configuration = builder.Build();//注册源
                foreach (var key in keyList)
                {
                    configuration = configuration.GetSection(key);
                }
                T t = configuration.Get<T>();
                return t;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        #endregion

    }
}
